/************************************************************
** Tim Huerter
** CS 235
** Final Project
** File name: grades.c
** Description:   This package contains the methods for 
**                initializing and maintaining the grades
**                linked list.
** 
************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "./studentList.h"

#define MAXGRADES 1000

static int gradeCount = 0;

/************************************************************
** function:      initGradeList
************************************************************/
gradeType* initGradeList() {
   gradeType* head = (gradeType*)malloc(sizeof(gradeType));
	gradeCount = 1;
   head->ident = -1;
   head->prev = NULL;
   head->count = 0;
   head->next = NULL;
	return head;
}

/************************************************************
** function:      deallocateGrades
************************************************************/
void deallocateGrades(gradeType* gList) {
   gradeType *temp = gList;
   gradeType *next;
   while (temp) {
      next = temp->next;
      free(temp);
      temp = next;
   }
}

/************************************************************
** function:      totalGradess
************************************************************/
int totalGradess(gradeType* gList) {
   return gList->count;
}

/************************************************************
** function:      getFirstGrade
************************************************************/
gradeType* getFirstGrade(gradeType* gList) {
   return gList;
}

/************************************************************
** function:      getNextGrade
************************************************************/
gradeType* getNextGrade(gradeType* gList) {
   return gList->next;
}

/************************************************************
** function:      getPrevGrade
************************************************************/
gradeType* getPrevGrade(gradeType* gList) {
   return gList->prev;
}

/************************************************************
** function:      getGrade
************************************************************/
gradeType* getGrade(int id, gradeType* gList) {
   gradeType* temp = gList;

   while(temp) {
      if(temp->ident == id) {
         return temp;
      }
      temp = getNextGrade(temp);
   }
   return NULL;
}

/************************************************************
** function:      addGrade
************************************************************/
void addGrade(gradeType grade, gradeType* stdGrades) {
   gradeType* temp;
   gradeType* current;
   gradeType* previous;
   
   grade.ident = gradeCount;
   grade.next = NULL;
   grade.count++;

   if (stdGrades->count <= 0) {
      memcpy(stdGrades, &grade, sizeof(gradeType));
      stdGrades->next = NULL;
      stdGrades->count = 0;
   }
   else if (stdGrades->ident >= grade.ident ) {
      temp = (gradeType*)malloc(sizeof(gradeType));
      memcpy(temp, stdGrades, sizeof(gradeType));
      memcpy(stdGrades, &grade, sizeof(gradeType));
      stdGrades->prev = NULL;      
      stdGrades->next = temp;
      temp->prev = stdGrades;
   } else {
      temp = (gradeType*)malloc(sizeof(gradeType));
      memcpy(temp, &grade, sizeof(gradeType));
      previous = stdGrades;
      current = stdGrades->next; 
      while ((current != NULL) && strcmp(current->name,temp->name)<0) 
      {
         previous = current;
         current = current->next;
      }
      temp->next=previous->next;
      previous->next=temp;
      temp->prev = previous;
   }
   stdGrades->count++;
   gradeCount++;
}
   
/************************************************************
** function:      delGrade
************************************************************/
void delGrade(int id, gradeType* gList) {
   gradeType* temp = getGrade(id, gList);
   gradeType* prev;
   gradeType* next;

   if(temp) {
      prev = getPrevGrade(temp);
      next = getNextGrade(temp);
      printf("deleting ...\n");
      printGrade(temp);

      if(gList->ident == id) {
         if (next) {
            memcpy(gList, next, sizeof(gradeType));
            gList->prev = NULL;
         } else {
            memset(gList, 0, sizeof(gradeType));
            gList->next = NULL;
            gList->ident = -1;
            gradeCount = 0;
         }
      } else {
         if(next) {
            prev->next = next;
            next->prev = prev;
         } else {
            prev->next = NULL;
         }
         free(temp);
         gradeCount--;
      }
   } else {
      printf("Could not find grade to delete\n");
   }

}

/************************************************************
** function:      printGrade
************************************************************/
void printGrade(gradeType* grade) {
   printf("Grade id %d: %s %6.2f\n", grade->ident, grade->name, grade->grade);
}

/************************************************************
** function:      printGrades
************************************************************/
void printGrades(gradeType* gList) {
   gradeType* temp = gList;
   
   if(temp->count > 0) {
      while (temp) {
         printGrade(temp);
         temp = getNextGrade(temp);
      }
   } else {
      printf("No Grades\n");
   }
}

/************************************************************
** function:      editGrade
************************************************************/
gradeType* editGrade(int id, gradeType* gList) {
   gradeType *temp = getGrade(id, gList);
   float newGrade = 0.0;
   char val[3];
   
   printf("Editing grade: %s [%f]\nfor \nstudent: ", temp->name, temp->grade);
   printStudent(getActiveStudent());
   printf("\nIs this correct ('y' or 'n')?");
   scanf("%s", val);
   
   if((val[0] == 'y') || (val[0] == 'Y')) {
      printf("\nPlease enter the new grade: ");
      scanf("%f", &newGrade);
      temp->grade = newGrade;
   }
   printf("Grade: %s [%f]\nfor \nstudent: ", temp->name, temp->grade);
   printStudent(getActiveStudent());

}

/************************************************************
** function:      copyGradeList
************************************************************/
/*void copyGradeList(studentType *s, gradeType* g) {
   printf("g name is: %s", g->name);
   printf("g ident is: %d", g->ident);
   gradeType *tempG = g;
   studentType *tempS = s;
   
   initGradeList(NULL);
   printf("tempG ident is: %d", tempG->ident);*/
   

//}
bool checkGradeID(gradeType* gList, int selection){
   gradeType* temp = gList;
   bool result = false;

   while (temp) {
      if (temp->ident == selection) {
      	result = true;
      }
      temp = getNextGrade(temp);
   }
   return result;
}

